<template>
  <el-container>
    <el-aside v-loading="loading" width="250px">
      <el-container>
        <el-header>
          <el-input v-model="menuName" clearable placeholder="输入菜单名称进行过滤"></el-input>
        </el-header>
        <el-main class="nopadding">
          <el-tree class="menu" node-key="menuId" ref="menu" show-checkbox check-strictly draggable
                   :data="menuList"
                   :props="menuProps"
                   :highlight-current="true"
                   :expand-on-click-node="false"
                   :filter-node-method="menuFilter"
                   :current-node-key="currentMenuId"
                   @node-click="menuClick" @node-drop="nodeDrop">
            <template #default="{node, data}">
							<span class="custom-tree-node">
								<span class="label">
									{{ node.label }}
								</span>
								<span class="do">
									<el-button icon="el-icon-plus" size="small"
                             @click.stop="handleAdd(node, data)"></el-button>
								</span>
							</span>
            </template>
          </el-tree>
        </el-main>
        <el-footer style="height:51px;">
          <el-button icon="el-icon-plus" size="small" type="primary" @click="handleAdd"></el-button>
          <el-button icon="el-icon-delete" plain size="small" type="danger" @click="handleDelete"></el-button>
        </el-footer>
      </el-container>
    </el-aside>
    <el-main ref="main" class="nopadding" style="padding:20px;">
      <el-row :gutter="40" v-if="!form.name">
        <el-col>
          <el-empty :image-size="100" description="请选择左侧菜单后操作"></el-empty>
        </el-col>
      </el-row>
      <el-row :gutter="40" v-else>
        <el-col :lg="10">
          <h2>{{ form.meta.title || "新增菜单" }}</h2>
          <el-form ref="form" label-position="left" label-width="80px" :model="form" :rules="rules">
            <el-form-item label="上级菜单" prop="parentId">
              <el-cascader disabled clearable placeholder="顶级菜单" v-model="form.parentId" :options="parentMenuList"
                           :props="parentMenuProps"
                           :show-all-levels="false"></el-cascader>
            </el-form-item>
            <el-form-item label="显示名称" prop="metaTitle">
              <el-input v-model="form.meta.title" clearable placeholder="菜单显示名字"></el-input>
            </el-form-item>
            <el-form-item label="别名" prop="name">
              <el-input v-model="form.name" clearable placeholder="菜单别名"></el-input>
              <div class="el-form-item-msg">
                系统唯一且与内置组件名一致，否则导致缓存失效。如类型为Iframe的菜单，别名将代替源地址显示在地址栏
              </div>
            </el-form-item>
            <el-form-item label="类型" prop="metaType">
              <el-radio-group v-model="form.meta.type">
                <el-radio-button label="directory">目录</el-radio-button>
                <el-radio-button label="menu">菜单</el-radio-button>
                <el-radio-button label="iframe">Iframe</el-radio-button>
                <el-radio-button label="link">外链</el-radio-button>
                <el-radio-button label="button">按钮</el-radio-button>
              </el-radio-group>
            </el-form-item>
            <el-form-item label="购买类型" prop="buyType">
              <el-radio-group v-model="form.buyType">
                <el-radio-button label="0">平台菜单</el-radio-button>
                <el-radio-button label="1">基本菜单</el-radio-button>
                <el-radio-button label="2">赠送菜单</el-radio-button>
                <el-radio-button label="3">付费菜单</el-radio-button>
              </el-radio-group>
            </el-form-item>
            <el-form-item label="路由地址" prop="path"
                          v-show="form.meta.type !== 'button'">
              <el-input v-model="form.path" clearable placeholder="路由地址"></el-input>
            </el-form-item>
            <el-form-item label="菜单图标" prop="metaIcon" v-show="form.meta.type === 'menu' || form.meta.type === 'directory'">
              <jcx-icon-select v-model="form.meta.icon" clearable></jcx-icon-select>
            </el-form-item>
            <el-form-item label="视图" prop="component" v-show="form.meta.type === 'menu'">
              <el-input v-model="form.component" clearable placeholder="">
                <template #prepend>views/</template>
              </el-input>
              <div class="el-form-item-msg">如父节点、链接或Iframe等没有视图的菜单不需要填写</div>
            </el-form-item>
            <el-form-item label="重定向" prop="redirect" v-show="form.meta.type === 'menu'">
              <el-input v-model="form.redirect" clearable placeholder=""></el-input>
              <div class="el-form-item-msg">填入需要重定向到的路由地址</div>
            </el-form-item>
            <el-form-item label="菜单高亮" prop="meta.active" v-show="form.meta.type === 'menu'">
              <el-input v-model="form.meta.active" clearable placeholder=""></el-input>
              <div class="el-form-item-msg">子节点或详情页需要高亮的上级菜单路由地址</div>
            </el-form-item>
            <el-form-item label="标签" prop="tag" v-show="form.meta.type === 'menu'">
              <el-input v-model="form.meta.tag" clearable placeholder=""></el-input>
            </el-form-item>
            <el-form-item label="颜色" prop="color" v-show="form.meta.type === 'menu'">
              <el-color-picker v-model="form.meta.color" :predefine="predefineColors"></el-color-picker>
            </el-form-item>
            <el-form-item label="整页路由" prop="fullpage" v-show="form.meta.type === 'menu'">
              <el-switch v-model="form.meta.fullpage"/>
            </el-form-item>
            <el-form-item label="是否隐藏" prop="meta.hidden">
              <el-checkbox v-model="form.meta.hidden">隐藏菜单</el-checkbox>
              <el-checkbox v-model="form.meta.hiddenBreadcrumb">隐藏面包屑</el-checkbox>
              <div class="el-form-item-msg">菜单不显示在导航中，但用户依然可以访问，例如详情页</div>
            </el-form-item>
            <el-form-item label="状态" prop="status">
              <el-switch v-model="form.status"/>
            </el-form-item>
            <el-form-item label="排序" prop="sort">
              <el-input-number v-model="form.sort" :precision="2" :min="1" :step="0.01"
                               controls-position="right"></el-input-number>
            </el-form-item>
            <el-form-item>
              <el-button :loading="saveing" type="primary" @click="handleUpdate">保 存</el-button>
            </el-form-item>
          </el-form>
        </el-col>
        <el-col :lg="14" class="apilist">
          <h2>接口权限</h2>
          <jcx-form-table v-model="form.apiList" :addTemplate="apiListTemplate" placeholder="暂无匹配接口权限">
            <el-table-column label="名称" prop="powerName">
              <template #default="scope">
                <el-input v-model="scope.row.powerName" placeholder="请输入内容"></el-input>
              </template>
            </el-table-column>
            <el-table-column label="标识" prop="powerCode">
              <template #default="scope">
                <el-input v-model="scope.row.powerCode" placeholder="请输入内容"></el-input>
              </template>
            </el-table-column>
            <el-table-column label="路径" prop="powerPath">
              <template #default="scope">
                <el-input v-model="scope.row.powerPath" placeholder="请输入内容"></el-input>
              </template>
            </el-table-column>
          </jcx-form-table>
        </el-col>
      </el-row>
    </el-main>
  </el-container>
</template>

<script>
let newMenuIndex = 1;

module.exports = {
  name: "Menu",
  data() {
    return {
      // 遮罩层
      loading: true,
      // 保存遮罩层
      saveing: false,
      // 查询用菜单名称
      menuName: '',
      currentMenuId: '',
      // 菜单列表数据
      menuList: [],
      // 父菜单列表数据
      parentMenuList: [],
      // 菜单规则
      menuProps: {
        label: (data) => {
          return data.meta.title
        }
      },
      // 父菜单规则
      parentMenuProps: {
        value: 'menuId',
        label: 'title',
        checkStrictly: true
      },
      // 表单
      form: {},
      // 规则
      rules: {},
      // 颜色预设
      predefineColors: [
        '#ff4500',
        '#ff8c00',
        '#ffd700',
        '#67C23A',
        '#00ced1',
        '#409EFF',
        '#c71585'
      ],
      // apiList
      apiListTemplate: {
        powerName: "",
        powerCode: "",
        powerPath: ""
      },
    }
  },
  watch: {
    menuName(val) {
      this.$refs.menu.filter(val);
    }
  },
  created() {
    this.getList(null);
  },
  methods: {
    //简单化菜单
    treeToMap(tree) {
      const map = []
      tree.forEach(item => {
        let obj = {
          menuId: item.menuId,
          parentId: item.parentId,
          title: item.meta.title,
          children: item.children && item.children.length > 0 ? this.treeToMap(item.children) : null
        }
        map.push(obj)
      })
      return map
    },
    /** 查询部门列表 */
    getList(menuId) {
      this.loading = true;
      this.$API.menu.pageListMenu.get(null).then(response => {
        if (response.status) {
          this.menuList = response.data.records;
          this.parentMenuList = this.treeToMap(this.menuList)
          if (menuId) {
            this.$nextTick(() => {
              this.$refs.menu.setCurrentKey(menuId);
            });
          }
        } else {
          this.$message.warning(response.msg);
        }
        this.loading = false;
      });
    },
    /** 菜单树过滤 */
    menuFilter(value, data) {
      if (!value) return true;
      let targetText = data.meta.title;
      return targetText.indexOf(value) !== -1;
    },
    /** 菜单树拖拽 */
    nodeDrop(draggingNode, dropNode, dropType) {
      this.form = {};
      this.$message(`拖拽对象：${draggingNode.data.meta.title}, 释放对象：${dropNode.data.meta.title}, 释放对象的位置：${dropType}`)
    },
    /** 菜单树点击 */
    menuClick(data, node) {
      this.reset();
      this.$API.menu.getMenuById.get(data.menuId).then(response => {
        if (response.status) {
          this.form = response.data;
        } else {
          this.$message.warning(response.msg);
        }
      });
    },
    /** 新增按钮操作 */
    handleAdd(node, data) {
      let newMenuName = "未命名" + newMenuIndex++;
      let newMenuData = {
        parentId: data ? data.menuId : "0",
        name: newMenuName,
        meta: {
          title: newMenuName,
          type: "menu"
        }
      };
      this.loading = true;
      this.$API.menu.addMenu.post({
        parentId: newMenuData.parentId,
        name: newMenuData.name,
        metaTitle: newMenuData.meta.title,
        metaType: newMenuData.meta.type,
      }).then(response => {
        if (response.status) {
          this.$message.success(response.msg);
          this.getList(response.data);
          this.$API.menu.getMenuById.get(response.data).then(response2 => {
            if (response2.status) {
              this.form = response2.data;
            } else {
              this.$alert(response.msg, "提示", {type: 'error'});
            }
          });
        } else {
          newMenuIndex--;
          this.$alert(response.msg, "提示", {type: 'error'});
        }
        this.loading = false;
      });
    },
    /** 删除按钮操作 */
    handleDelete() {
      let CheckedNodes = this.$refs.menu.getCheckedNodes()
      if (CheckedNodes.length === 0) {
        this.$message.warning("请选择需要删除的菜单项")
        return false;
      }
      this.$confirm('确认删除已选择的菜单吗？', '提示', {
        type: 'warning',
        confirmButtonText: '删除',
        confirmButtonClass: 'el-button--danger'
      }).then(confirm => {
        if (confirm === 'confirm') {
          this.loading = true;
          let menuIds = CheckedNodes.map(item => item.menuId);
          this.$API.menu.delMenus.delete(menuIds).then(response => {
            if (response.status) {
              this.$message.success(response.msg);
              this.form = {};
              this.getList(null);
            } else {
              this.$alert(response.msg, "提示", {type: 'error'});
            }
            this.loading = false;
          })
        }
      }).catch(() => {
      })
    },
    /** 表单重置 */
    reset() {
      this.form = {
        menuId: "",
        parentId: "",
        name: "",
        path: "",
        component: "",
        redirect: "",
        buyType: "",
        status: "",
        sort: "",
        meta: {
          title: "",
          icon: "",
          active: "",
          color: "",
          type: "menu",
          fullpage: false,
          tag: "",
          hidden: false,
          hiddenBreadcrumb: false
        },
        apiList: []
      };
      this.$nextTick(() => {
        if (this.$refs['form']) {
          this.$refs['form'].clearValidate();
          this.$refs['form'].resetFields();
        }
      });
    },
    /** 修改按钮操作 */
    handleUpdate() {
      if (!this.form.meta.color) {
        this.form.meta.color = ''
      }
      this.$refs["form"].validate(valid => {
        if (valid) {
          this.saveing = true;
          this.$API.menu.editMenu.put({
            menuId: this.form.menuId,
            parentId: this.form.parentId,
            name: this.form.name,
            path: this.form.path,
            component: this.form.component,
            redirect: this.form.redirect,
            sort: this.form.sort,
            buyType: this.form.buyType,
            metaTitle: this.form.meta.title,
            metaIcon: this.form.meta.icon,
            metaType: this.form.meta.type,
            metaColor: this.form.meta.color,
            metaTag: this.form.meta.tag,
            metaActive: this.form.meta.active,
            metaHidden: this.form.meta.hidden,
            metaHiddenBreadcrumb: this.form.meta.hiddenBreadcrumb,
            metaFullPage: this.form.meta.fullpage,
            platformMenuPowerEditVoList: this.form.apiList,
            status: this.form.status
          }).then(response => {
            if (response.status) {
              this.$message.success(response.msg)
              this.$API.menu.getMenuById.get(this.form.menuId).then(response2 => {
                if (response2.status) {
                  this.form = response2.data
                  this.saveing = false;
                  this.getList(this.form.menuId);
                } else {
                  this.$message.warning(response2.msg);
                  this.saveing = false;
                }
              });
            } else {
              this.$alert(response.msg, "提示", {type: 'error'});
              this.saveing = false;
            }
          });
        }
      });
    },
  }
}
</script>

<style scoped>
.custom-tree-node {
  display: flex;
  flex: 1;
  align-items: center;
  justify-content: space-between;
  font-size: 14px;
  padding-right: 24px;
  height: 100%;
}

.custom-tree-node {
  display: flex;
  flex: 1;
  align-items: center;
  justify-content: space-between;
  font-size: 14px;
  padding-right: 24px;
  height: 100%;
}

.custom-tree-node .label {
  display: flex;
  align-items: center;;
  height: 100%;
}

.custom-tree-node .label .el-tag {
  margin-left: 5px;
}

.custom-tree-node .do {
  display: none;
}

.custom-tree-node .do i {
  margin-left: 5px;
  color: #999;
}

.custom-tree-node .do i:hover {
  color: #333;
}

.custom-tree-node:hover .do {
  display: inline-block;
}

h2 {
  font-size: 17px;
  color: #3c4a54;
  padding: 0 0 30px 0;
}

.apilist {
  border-left: 1px solid #eee;
}

[data-theme="dark"] h2 {
  color: #fff;
}

[data-theme="dark"] .apilist {
  border-color: #434343;
}
</style>
